package com.xuan.service.pg.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xuan.dto.pg.bazi.*;
import com.xuan.mapper.pg.PgBaZiMapper;
import com.xuan.pojo.pg.PgBaZi;
import com.xuan.service.pg.PgBaZiService;
import com.xuan.utils.xuan.bazi.BaZi;
import com.xuan.utils.xuan.bazi.BaZiMap;
import com.xuan.utils.xuan.bazi.BaZiSetting;
import com.xuan.utils.xuan.bazi.BaZiUtil;
import com.xuan.utils.xuan.bazi.utils.BaZiDaYunLiuNianUtil;
import com.xuan.utils.xuan.bazi.utils.BaZiShenShaUtil;
import com.xuan.vo.pg.bazi.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 八字排盘Impl
 */
@Service
public class PgBaZiServiceImpl extends ServiceImpl<PgBaZiMapper, PgBaZi> implements PgBaZiService {

    /**
     * 开始排盘
     *
     * @param dto 八字排盘数据接收类
     * @return 排盘数据
     */
    @Override
    public PgBaZiVo starts(PgBaZiDto dto) {

        // 1、拷贝设置
        BaZiSetting setting = new BaZiSetting();
        BeanUtils.copyProperties(dto, setting);

        // 2、排盘
        BaZi baZi = new BaZi(setting);

        // 3、返回数据
        PgBaZiVo vo = new PgBaZiVo();
        BeanUtils.copyProperties(baZi, vo);
        return vo;

    }

    /**
     * 初始化大运流年
     *
     * @param dto 大运流年初始化请求数据
     * @return 大运数据、流年数据、小运数据、流月数据、大运流年命盘数据、大运流年与其他干支的干支留意数据
     */
    @Override
    public PgBaZiDaYunLiuNianInitializeVo daYunLiuNianInitialize(PgBaZiDaYunLiuNianInitializeDto dto) {

        Map<String, String> shiShen = BaZiMap.SHI_SHEN_MING_PAN_MAP; // 十神，用于命盘（日干+其他干支为键）
        Map<String, List<String>> diZhiCangGan = BaZiMap.DI_ZHI_CANG_GAN; // 地支藏干（地支为键）
        Map<String, String> shiErZhangSheng = BaZiMap.SHI_ER_ZHANG_SHENG; // 十二长生（日干+地支为键）
        Map<String, String> kongWang = BaZiMap.KONG_WANG; // 空亡（干支为键）
        Map<String, String> naYin = BaZiMap.NA_YIN; // 纳音（干支为键）

        // 1、处理数据
        String ygz = dto.getYearGan() + dto.getYearZhi();   // 年干支
        String mgz = dto.getMonthGan() + dto.getMonthZhi(); // 月干支
        String dgz = dto.getDayGan() + dto.getDayZhi();     // 日干支
        String hgz = dto.getHourGan() + dto.getHourZhi();   // 时干支

        // 2、计算小运数据、流月数据
        BaZiDaYunLiuNianUtil dylnUtil = new BaZiDaYunLiuNianUtil(dto.getDate(), dto.getDayGan(), dto.getSex(), dto.getQiYunLiuPai());
        dylnUtil.daYun(); // 计算大运数据
        dylnUtil.liuNian(1); // 计算流年数据
        dylnUtil.xiaoYun(1); // 计算小运数据
        dylnUtil.liuYue(1, 1, dto.getDate().getYear() + 1900); // 计算流月数据
        List<List<String>> daYun = dylnUtil.getDaYun(); // 获取大运数据
        List<List<String>> liuNian = dylnUtil.getLiuNian(); // 获取流年数据
        List<List<String>> xiaoYun = dylnUtil.getXiaoYun(); // 获取小运数据
        List<List<String>> liuYue = dylnUtil.getLiuYue(); // 获取流月数据

        // 3、处理大运干支、流年干支
        String dyGz = ""; // 大运干支
        String lnGz = ""; // 流年干支
        String dyG = ""; // 大运干
        String dyZ = ""; // 大运支
        String lnG = ""; // 流年干
        String lnZ = ""; // 流年支
        if (xiaoYun.size() != 0) {
            dyGz = xiaoYun.get(0).get(2);
        } else {
            dyGz = daYun.get(1).get(2);
        }
        if (daYun.size() != 0) {
            lnGz = liuNian.get(0).get(2);
        }
        if (StringUtils.isNotBlank(dyGz) && dyGz.length() >= 2) {
            dyG = dyGz.substring(0, 1); // 大运干
            dyZ = dyGz.substring(1, 2); // 大运支
        }
        if (StringUtils.isNotBlank(lnGz) && lnGz.length() >= 2) {
            lnG = lnGz.substring(0, 1); // 流年干
            lnZ = lnGz.substring(1, 2); // 流年支
        }

        // 4.1、拷贝干支关系显示选项
        GanZhiGuanXiOption option = new GanZhiGuanXiOption();
        BeanUtils.copyProperties(dto, option);
        // 4.2、计算干支留意
        List<String> tianGanLiuYi = BaZiUtil.tgLy(option, ygz, mgz, dgz, hgz, dyGz, lnGz, null, null, null); // 天干留意
        List<String> diZhiLiuYi = BaZiUtil.dzLy(option, ygz, mgz, dgz, hgz, dyGz, lnGz, null, null, null);   // 地支留意

        // 5、计算命盘
        // 5.1、计算主星
        String daYunZhuXing = shiShen.get(dto.getDayGan() + dyG);// 大运主星
        String liuNianZhuXing = shiShen.get(dto.getDayGan() + lnG); // 流年主星
        // 5.2、计算藏干
        List<String> daYunCangGan = diZhiCangGan.get(dyZ);// 大运藏干
        List<String> liuNianCangGan = diZhiCangGan.get(lnZ);// 流年藏干
        // 5.3、计算副星
        List<String> daYunFuXing = new ArrayList<>();
        List<String> liuNianFuXing = new ArrayList<>();
        for (String cangGan : daYunCangGan) {
            daYunFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 大运副星
        }
        for (String cangGan : liuNianCangGan) {
            liuNianFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 流年副星
        }
        // 5.4、计算地势
        String daYunDiShi = shiErZhangSheng.get(dto.getDayGan() + dyZ); // 大运地势
        String liuNianDiShi = shiErZhangSheng.get(dto.getDayGan() + lnZ); // 流年地势
        // 5.5、计算空亡
        String daYunKongWang = kongWang.get(dyGz); // 大运空亡
        String liuNianKongWang = kongWang.get(lnGz); // 流年空亡
        // 5.6、计算纳音
        String daYunNaYin = naYin.get(dyGz); // 大运纳音
        String liuNianNaYin = naYin.get(lnGz); // 流年纳音
        // 5.7、计算神煞
        BaZiSetting baZiSetting = new BaZiSetting();
        BeanUtils.copyProperties(dto, baZiSetting);
        List<String> baZi = Arrays.asList(ygz, mgz, dgz, hgz);
        List<String> yunNianGanZhi = Arrays.asList(dyGz, lnGz);
        BaZiShenShaUtil ssUtil = new BaZiShenShaUtil(baZiSetting, baZi, dto.getYearGanZhiNaYinWuXing(), dto.getSeason(), yunNianGanZhi);
        List<String> daYunShenSha = ssUtil.getDaYunShenSha(); // 大运神煞
        List<String> liuNianShenSha = ssUtil.getLiuNianShenSha(); // 流年神煞

        // 6、设置数据并返回
        PgBaZiDaYunLiuNianInitializeVo vo = new PgBaZiDaYunLiuNianInitializeVo();
        vo.setDaYun(daYun); // 大运
        vo.setLiuNian(liuNian); // 流年
        vo.setXiaoYun(xiaoYun); // 小运
        vo.setLiuYue(liuYue); // 流月
        vo.setTianGanLiuYi(tianGanLiuYi); // 天干留意
        vo.setDiZhiLiuYi(diZhiLiuYi); // 地支留意
        vo.setDaYunZhuXing(daYunZhuXing); // 大运主星
        vo.setLiuNianZhuXing(liuNianZhuXing); // 流年主星
        vo.setDaYunGanZhi(dyGz); // 大运干支
        vo.setLiuNianGanZhi(lnGz); // 流年干支
        vo.setDaYunCangGan(daYunCangGan); // 大运藏干
        vo.setLiuNianCangGan(liuNianCangGan); // 流年藏干
        vo.setDaYunFuXing(daYunFuXing); // 大运副星
        vo.setLiuNianFuXing(liuNianFuXing); // 流年副星
        vo.setDaYunDiShi(daYunDiShi); // 大运地势
        vo.setLiuNianDiShi(liuNianDiShi); // 流年地势
        vo.setDaYunKongWang(daYunKongWang); // 大运空亡
        vo.setLiuNianKongWang(liuNianKongWang); // 流年空亡
        vo.setDaYunNaYin(daYunNaYin); // 大运纳音
        vo.setLiuNianNaYin(liuNianNaYin); // 流年纳音
        vo.setDaYunShenSha(daYunShenSha); // 大运神煞
        vo.setLiuNianShenSha(liuNianShenSha); // 流年神煞
        return vo;

    }

    /**
     * 大运切换
     *
     * @param dto 大运切换请求数据
     * @return 流年数据、小运数据、流月数据、大运流年命盘数据、大运流年与其他干支的干支留意数据
     */
    @Override
    public PgBaZiDaYunVo daYun(PgBaZiDaYunDto dto) {

        Map<String, String> shiShen = BaZiMap.SHI_SHEN_MING_PAN_MAP; // 十神，用于命盘（日干+其他干支为键）
        Map<String, List<String>> diZhiCangGan = BaZiMap.DI_ZHI_CANG_GAN; // 地支藏干（地支为键）
        Map<String, String> shiErZhangSheng = BaZiMap.SHI_ER_ZHANG_SHENG; // 十二长生（日干+地支为键）
        Map<String, String> kongWang = BaZiMap.KONG_WANG; // 空亡（干支为键）
        Map<String, String> naYin = BaZiMap.NA_YIN; // 纳音（干支为键）

        // 1、处理数据
        String ygz = dto.getYearGan() + dto.getYearZhi();    // 年干支
        String mgz = dto.getMonthGan() + dto.getMonthZhi();  // 月干支
        String dgz = dto.getDayGan() + dto.getDayZhi();      // 日干支
        String hgz = dto.getHourGan() + dto.getHourZhi();    // 时干支
        String dyGz = dto.getDaYunGan() + dto.getDaYunZhi(); // 大运干支

        // 2.1、计算流年数据、小运数据、流月数据
        BaZiDaYunLiuNianUtil dylnUtil = new BaZiDaYunLiuNianUtil(dto.getDate(), dto.getDayGan(), dto.getSex(), dto.getQiYunLiuPai());
        dylnUtil.daYun(); // 计算大运数据
        dylnUtil.liuNian(dto.getDaYunLun()); // 计算流年数据
        dylnUtil.xiaoYun(dto.getDaYunLun()); // 计算小运数据
        dylnUtil.liuYue(dto.getDaYunLun(), dto.getLiuNianLun(), dto.getSolarYear()); // 计算流月数据
        List<List<String>> liuNian = dylnUtil.getLiuNian(); // 获取流年数据
        List<List<String>> xiaoYun = dylnUtil.getXiaoYun(); // 获取小运数据
        List<List<String>> liuYue = dylnUtil.getLiuYue(); // 获取流月数据

        // 3、处理流年干支
        String lnG = ""; // 流年干
        String lnZ = ""; // 流年支
        String lnGz = liuNian.get(dto.getLiuNianLun() - 1).get(2); // 流年干支
        if (StringUtils.isNotBlank(lnGz) && lnGz.length() >= 2) {
            lnG = lnGz.substring(0, 1); // 流年干
            lnZ = lnGz.substring(1, 2); // 流年支
        }

        // 4.1、拷贝干支关系显示选项
        GanZhiGuanXiOption option = new GanZhiGuanXiOption();
        BeanUtils.copyProperties(dto, option);
        // 4.2、计算干支留意
        List<String> tianGanLiuYi = BaZiUtil.tgLy(option, ygz, mgz, dgz, hgz, dyGz, lnGz, null, null, null); // 天干留意
        List<String> diZhiLiuYi = BaZiUtil.dzLy(option, ygz, mgz, dgz, hgz, dyGz, lnGz, null, null, null);   // 地支留意

        // 5、计算命盘
        // 5.1、计算主星
        String daYunZhuXing = shiShen.get(dto.getDayGan() + dto.getDaYunGan());// 大运主星
        String liuNianZhuXing = shiShen.get(dto.getDayGan() + lnG); // 流年主星
        // 5.2、计算藏干
        List<String> daYunCangGan = diZhiCangGan.get(dto.getDaYunZhi());// 大运藏干
        List<String> liuNianCangGan = diZhiCangGan.get(lnZ);// 流年藏干
        // 5.3、计算副星
        List<String> daYunFuXing = new ArrayList<>();
        List<String> liuNianFuXing = new ArrayList<>();
        for (String cangGan : daYunCangGan) {
            daYunFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 大运副星
        }
        for (String cangGan : liuNianCangGan) {
            liuNianFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 流年副星
        }
        // 5.4、计算地势
        String daYunDiShi = shiErZhangSheng.get(dto.getDayGan() + dto.getDaYunZhi()); // 大运地势
        String liuNianDiShi = shiErZhangSheng.get(dto.getDayGan() + lnZ); // 流年地势
        // 5.5、计算空亡
        String daYunKongWang = kongWang.get(dyGz); // 大运空亡
        String liuNianKongWang = kongWang.get(lnGz); // 流年空亡
        // 5.6、计算纳音
        String daYunNaYin = naYin.get(dyGz); // 大运纳音
        String liuNianNaYin = naYin.get(lnGz); // 流年纳音
        // 5.7、计算神煞
        BaZiSetting baZiSetting = new BaZiSetting();
        BeanUtils.copyProperties(dto, baZiSetting);
        List<String> baZi = Arrays.asList(ygz, mgz, dgz, hgz);
        List<String> yunNianGanZhi = Arrays.asList(dyGz, lnGz);
        BaZiShenShaUtil ssUtil = new BaZiShenShaUtil(baZiSetting, baZi, dto.getYearGanZhiNaYinWuXing(), dto.getSeason(), yunNianGanZhi);
        List<String> daYunShenSha = ssUtil.getDaYunShenSha(); // 大运神煞
        List<String> liuNianShenSha = ssUtil.getLiuNianShenSha(); // 流年神煞

        // 6、设置数据并返回
        PgBaZiDaYunVo vo = new PgBaZiDaYunVo();
        vo.setLiuNian(liuNian); // 流年
        vo.setXiaoYun(xiaoYun); // 小运
        vo.setLiuYue(liuYue); // 流月
        vo.setTianGanLiuYi(tianGanLiuYi); // 天干留意
        vo.setDiZhiLiuYi(diZhiLiuYi); // 地支留意
        vo.setDaYunZhuXing(daYunZhuXing); // 大运主星
        vo.setLiuNianZhuXing(liuNianZhuXing); // 流年主星
        vo.setDaYunGanZhi(dyGz); // 大运干支
        vo.setLiuNianGanZhi(lnGz); // 流年干支
        vo.setDaYunCangGan(daYunCangGan); // 大运藏干
        vo.setLiuNianCangGan(liuNianCangGan); // 流年藏干
        vo.setDaYunFuXing(daYunFuXing); // 大运副星
        vo.setLiuNianFuXing(liuNianFuXing); // 流年副星
        vo.setDaYunDiShi(daYunDiShi); // 大运地势
        vo.setLiuNianDiShi(liuNianDiShi); // 流年地势
        vo.setDaYunKongWang(daYunKongWang); // 大运空亡
        vo.setLiuNianKongWang(liuNianKongWang); // 流年空亡
        vo.setDaYunNaYin(daYunNaYin); // 大运纳音
        vo.setLiuNianNaYin(liuNianNaYin); // 流年纳音
        vo.setDaYunShenSha(daYunShenSha); // 大运神煞
        vo.setLiuNianShenSha(liuNianShenSha); // 流年神煞
        return vo;

    }

    /**
     * 流年\小运切换
     *
     * @param dto 流年\小运切换请求数据
     * @return 流月数据、流年命盘数据、流年与其他干支的干支留意数据
     */
    @Override
    public PgBaZiLiuNianVo liuNian(PgBaZiLiuNianDto dto) {

        Map<String, String> shiShen = BaZiMap.SHI_SHEN_MING_PAN_MAP; // 十神，用于命盘（日干+其他干支为键）
        Map<String, List<String>> diZhiCangGan = BaZiMap.DI_ZHI_CANG_GAN; // 地支藏干（地支为键）
        Map<String, String> shiErZhangSheng = BaZiMap.SHI_ER_ZHANG_SHENG; // 十二长生（日干+地支为键）
        Map<String, String> kongWang = BaZiMap.KONG_WANG; // 空亡（干支为键）
        Map<String, String> naYin = BaZiMap.NA_YIN; // 纳音（干支为键）

        // 1、处理数据
        String ygz = dto.getYearGan() + dto.getYearZhi();        // 年干支
        String mgz = dto.getMonthGan() + dto.getMonthZhi();      // 月干支
        String dgz = dto.getDayGan() + dto.getDayZhi();          // 日干支
        String hgz = dto.getHourGan() + dto.getHourZhi();        // 时干支
        String dyGz = dto.getDaYunGan() + dto.getDaYunZhi();     // 大运干支
        String lnGz = dto.getLiuNianGan() + dto.getLiuNianZhi(); // 流年干支

        // 2、计算流月数据
        BaZiDaYunLiuNianUtil dylnUtil = new BaZiDaYunLiuNianUtil(dto.getDate(), dto.getDayGan(), dto.getSex(), dto.getQiYunLiuPai());
        dylnUtil.daYun(); // 计算大运数据
        dylnUtil.liuNian(dto.getDaYunLun()); // 计算流年数据
        dylnUtil.liuYue(dto.getDaYunLun(), dto.getLiuNianLun(), dto.getSolarYear()); // 计算流月数据
        List<List<String>> liuYue = dylnUtil.getLiuYue(); // 获取流月数据

        // 3.1、拷贝干支关系显示选项
        GanZhiGuanXiOption option = new GanZhiGuanXiOption();
        BeanUtils.copyProperties(dto, option);
        // 3.2、计算干支留意
        List<String> tianGanLiuYi = BaZiUtil.tgLy(option, ygz, mgz, dgz, hgz, dyGz, lnGz, null, null, null); // 天干留意
        List<String> diZhiLiuYi = BaZiUtil.dzLy(option, ygz, mgz, dgz, hgz, dyGz, lnGz, null, null, null);   // 地支留意

        // 4、计算命盘数据
        // 4.1、计算主星
        String daYunZhuXing = shiShen.get(dto.getDayGan() + dto.getDaYunGan()); // 大运主星
        String liuNianZhuXing = shiShen.get(dto.getDayGan() + dto.getLiuNianGan()); // 流年主星
        // 4.2、计算藏干
        List<String> daYunCangGan = diZhiCangGan.get(dto.getDaYunZhi()); // 大运藏干
        List<String> liuNianCangGan = diZhiCangGan.get(dto.getLiuNianZhi());// 流年藏干
        // 4.3、计算副星
        List<String> daYunFuXing = new ArrayList<>();
        List<String> liuNianFuXing = new ArrayList<>();
        for (String cangGan : daYunCangGan) {
            daYunFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 大运副星
        }
        for (String cangGan : liuNianCangGan) {
            liuNianFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 流年副星
        }
        // 4.4、计算地势
        String daYunDiShi = shiErZhangSheng.get(dto.getDaYunGan() + dto.getDaYunZhi()); // 大运地势
        String liuNianDiShi = shiErZhangSheng.get(dto.getDayGan() + dto.getLiuNianZhi()); // 流年地势
        // 4.5、计算空亡
        String daYunKongWang = kongWang.get(dyGz); // 大运空亡
        String liuNianKongWang = kongWang.get(lnGz); // 流年空亡
        // 4.6、计算纳音
        String daYunNaYin = naYin.get(dyGz); // 大运纳音
        String liuNianNaYin = naYin.get(lnGz); // 流年纳音
        // 4.7、计算神煞
        BaZiSetting baZiSetting = new BaZiSetting();
        BeanUtils.copyProperties(dto, baZiSetting);
        List<String> baZi = Arrays.asList(ygz, mgz, dgz, hgz);
        List<String> yunNianGanZhi = Arrays.asList(dyGz, lnGz);
        BaZiShenShaUtil ssUtil = new BaZiShenShaUtil(baZiSetting, baZi, dto.getYearGanZhiNaYinWuXing(), dto.getSeason(), yunNianGanZhi);
        List<String> daYunShenSha = ssUtil.getDaYunShenSha(); // 大运神煞
        List<String> liuNianShenSha = ssUtil.getLiuNianShenSha(); // 流年神煞

        // 5、设置数据并返回
        PgBaZiLiuNianVo vo = new PgBaZiLiuNianVo();
        vo.setLiuYue(liuYue); // 流月
        vo.setTianGanLiuYi(tianGanLiuYi); // 天干留意
        vo.setDiZhiLiuYi(diZhiLiuYi); // 地支留意
        vo.setDaYunGanZhi(dyGz); // 大运干支
        vo.setLiuNianGanZhi(lnGz); // 流年干支
        vo.setDaYunZhuXing(daYunZhuXing); // 大运主星
        vo.setLiuNianZhuXing(liuNianZhuXing); // 流年主星
        vo.setDaYunCangGan(daYunCangGan); // 大运藏干
        vo.setLiuNianCangGan(liuNianCangGan); // 流年藏干
        vo.setDaYunFuXing(daYunFuXing); // 大运副星
        vo.setLiuNianFuXing(liuNianFuXing); // 流年副星
        vo.setDaYunDiShi(daYunDiShi); // 大运地势
        vo.setLiuNianDiShi(liuNianDiShi); // 流年地势
        vo.setDaYunKongWang(daYunKongWang); // 大运空亡
        vo.setLiuNianKongWang(liuNianKongWang); // 流年空亡
        vo.setDaYunNaYin(daYunNaYin); // 大运纳音
        vo.setLiuNianNaYin(liuNianNaYin); // 流年纳音
        vo.setDaYunShenSha(daYunShenSha); // 大运神煞
        vo.setLiuNianShenSha(liuNianShenSha); // 流年神煞
        return vo;

    }

    /**
     * 流月切换
     *
     * @param dto 流月切换请求数据
     * @return 流日数据、流月命盘数据、流月与其他干支的干支留意数据
     */
    @Override
    public PgBaZiLiuYueVo liuYue(PgBaZiLiuYueDto dto) {

        Map<String, String> shiShen = BaZiMap.SHI_SHEN_MING_PAN_MAP; // 十神，用于命盘（日干+其他干支为键）
        Map<String, List<String>> diZhiCangGan = BaZiMap.DI_ZHI_CANG_GAN; // 地支藏干（地支为键）
        Map<String, String> shiErZhangSheng = BaZiMap.SHI_ER_ZHANG_SHENG; // 十二长生（日干+地支为键）
        Map<String, String> kongWang = BaZiMap.KONG_WANG; // 空亡（干支为键）
        Map<String, String> naYin = BaZiMap.NA_YIN; // 纳音（干支为键）

        // 1、处理数据
        String ygz = dto.getYearGan() + dto.getYearZhi();        // 年干支
        String mgz = dto.getMonthGan() + dto.getMonthZhi();      // 月干支
        String dgz = dto.getDayGan() + dto.getDayZhi();          // 日干支
        String hgz = dto.getHourGan() + dto.getHourZhi();        // 时干支
        String dyGz = dto.getDaYunGan() + dto.getDaYunZhi();     // 大运干支
        String lnGz = dto.getLiuNianGan() + dto.getLiuNianZhi(); // 流年干支
        String lyGz = dto.getLiuYueGan() + dto.getLiuYueZhi();   // 流月干支

        // 2、计算流日数据
        BaZiDaYunLiuNianUtil dylnUtil = new BaZiDaYunLiuNianUtil(dto.getDate(), dto.getDayGan(), dto.getSex(), dto.getQiYunLiuPai());
        dylnUtil.liuRi(dto.getSolarYear(), dto.getSolarMonth()); // 计算流日数据
        List<List<String>> liuRi = dylnUtil.getLiuRi(); // 获取流日数据

        // 3.1、拷贝干支关系显示选项
        GanZhiGuanXiOption option = new GanZhiGuanXiOption();
        BeanUtils.copyProperties(dto, option);
        // 3.2、计算干支留意
        List<String> tianGanLiuYi = BaZiUtil.tgLy(option, ygz, mgz, dgz, hgz, dyGz, lnGz, lyGz, null, null); // 天干留意
        List<String> diZhiLiuYi = BaZiUtil.dzLy(option, ygz, mgz, dgz, hgz, dyGz, lnGz, lyGz, null, null);   // 地支留意

        // 4、计算命盘
        // 4.1、计算主星
        String liuYueZhuXing = shiShen.get(dto.getDayGan() + dto.getLiuYueGan()); // 流月主星
        // 4.2、计算藏干
        List<String> liuYueCangGan = diZhiCangGan.get(dto.getLiuYueZhi());// 流月藏干
        // 3.3、计算副星
        List<String> liuYueFuXing = new ArrayList<>();
        for (String cangGan : liuYueCangGan) {
            liuYueFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 流月副星
        }
        // 4.4、计算地势
        String liuYueDiShi = shiErZhangSheng.get(dto.getDayGan() + dto.getLiuYueZhi()); // 流月地势
        // 4.5、计算空亡
        String liuYueKongWang = kongWang.get(lyGz); // 流月空亡
        // 4.6、计算纳音
        String liuYueNaYin = naYin.get(lyGz); // 流月纳音
        // 4.7、计算神煞
        BaZiSetting baZiSetting = new BaZiSetting();
        BeanUtils.copyProperties(dto, baZiSetting);
        List<String> baZi = Arrays.asList(ygz, mgz, dgz, hgz);
        List<String> yunNianGanZhi = Arrays.asList("00", "00", lyGz);
        BaZiShenShaUtil ssUtil = new BaZiShenShaUtil(baZiSetting, baZi, dto.getYearGanZhiNaYinWuXing(), dto.getSeason(), yunNianGanZhi);
        List<String> liuYueShenSha = ssUtil.getLiuYueShenSha(); // 流月神煞

        // 5、设置数据并返回
        PgBaZiLiuYueVo vo = new PgBaZiLiuYueVo();
        vo.setLiuRi(liuRi); // 流日
        vo.setTianGanLiuYi(tianGanLiuYi); // 天干留意
        vo.setDiZhiLiuYi(diZhiLiuYi); // 地支留意
        vo.setLiuYueZhuXing(liuYueZhuXing); // 流月主星
        vo.setLiuYueGanZhi(lyGz); // 流月干支
        vo.setLiuYueCangGan(liuYueCangGan); // 流月藏干
        vo.setLiuYueFuXing(liuYueFuXing); // 流月副星
        vo.setLiuYueDiShi(liuYueDiShi); // 流月地势
        vo.setLiuYueKongWang(liuYueKongWang); // 流月空亡
        vo.setLiuYueNaYin(liuYueNaYin); // 流月纳音
        vo.setLiuYueShenSha(liuYueShenSha); // 流月神煞
        return vo;

    }

    /**
     * 胎命身切换
     *
     * @param dto 胎命身切换请求数据
     * @return 胎命身数据
     */
    @Override
    public PgBaZiTaiMingShenVo taiMingShen(PgBaZiTaiMingShenDto dto) {

        // 1、处理数据
        String ygz = dto.getYearGan() + dto.getYearZhi();          // 年干支
        String mgz = dto.getMonthGan() + dto.getMonthZhi();        // 月干支
        String dgz = dto.getDayGan() + dto.getDayZhi();            // 日干支
        String hgz = dto.getHourGan() + dto.getHourZhi();          // 时干支
        String tyGz = dto.getTaiYuanGan() + dto.getTaiYuanZhi();   // 胎元干支
        String txGz = dto.getTaiXiGan() + dto.getTaiXiZhi();       // 胎息干支
        String mgGz = dto.getMingGongGan() + dto.getMingGongZhi(); // 命宫干支
        String sgGz = dto.getShenGongGan() + dto.getShenGongZhi(); // 身宫干支

        Map<String, String> shiShen = BaZiMap.SHI_SHEN_MING_PAN_MAP; // 十神，用于命盘（日干+其他干支为键）
        Map<String, List<String>> diZhiCangGan = BaZiMap.DI_ZHI_CANG_GAN; // 地支藏干（地支为键）
        Map<String, String> shiErZhangSheng = BaZiMap.SHI_ER_ZHANG_SHENG; // 十二长生（日干+地支为键）
        Map<String, String> kongWang = BaZiMap.KONG_WANG; // 空亡（干支为键）
        Map<String, String> naYin = BaZiMap.NA_YIN; // 纳音（干支为键）

        // 2.1、拷贝干支关系显示选项
        GanZhiGuanXiOption option = new GanZhiGuanXiOption();
        BeanUtils.copyProperties(dto, option);
        // 2.2、计算干支留意
        List<String> tianGanLiuYi = BaZiUtil.tgLy(option, ygz, mgz, dgz, hgz, tyGz, txGz, mgGz, sgGz, null); // 天干留意
        List<String> diZhiLiuYi = BaZiUtil.dzLy(option, ygz, mgz, dgz, hgz, tyGz, txGz, mgGz, sgGz, null);   // 地支留意

        // 3、计算胎元、胎息、命宫、身宫命盘数据
        // 3.1、计算主星
        String taiYuanZhuXing = shiShen.get(dto.getDayGan() + dto.getTaiYuanGan());   // 胎元主星
        String taiXiZhuXing = shiShen.get(dto.getDayGan() + dto.getTaiXiGan());       // 胎息主星
        String mingGongZhuXing = shiShen.get(dto.getDayGan() + dto.getMingGongGan()); // 命宫主星
        String shenGongZhuXing = shiShen.get(dto.getDayGan() + dto.getShenGongGan()); // 身宫主星
        // 3.2、计算藏干
        List<String> taiYuanCangGan = diZhiCangGan.get(dto.getTaiYuanZhi());   // 胎元藏干
        List<String> taiXiCangGan = diZhiCangGan.get(dto.getTaiXiZhi());       // 胎息藏干
        List<String> mingGongCangGan = diZhiCangGan.get(dto.getMingGongZhi()); // 命宫藏干
        List<String> shenGongCangGan = diZhiCangGan.get(dto.getShenGongZhi()); // 身宫藏干
        // 3.3、计算副星
        List<String> taiYuanFuXing = new ArrayList<>();
        List<String> taiXiFuXing = new ArrayList<>();
        List<String> mingGongFuXing = new ArrayList<>();
        List<String> shenGongFuXing = new ArrayList<>();
        for (String cangGan : taiYuanCangGan) {
            taiYuanFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 胎元副星
        }
        for (String cangGan : taiXiCangGan) {
            taiXiFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 胎息副星
        }
        for (String cangGan : mingGongCangGan) {
            mingGongFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 命宫副星
        }
        for (String cangGan : shenGongCangGan) {
            shenGongFuXing.add(shiShen.get(dto.getDayGan() + cangGan)); // 身宫副星
        }
        // 3.4、计算地势
        String taiYuanDiShi = shiErZhangSheng.get(dto.getDayGan() + dto.getTaiYuanZhi());   // 胎元地势
        String taiXiDiShi = shiErZhangSheng.get(dto.getDayGan() + dto.getTaiXiZhi());       // 胎息地势
        String mingGongDiShi = shiErZhangSheng.get(dto.getDayGan() + dto.getMingGongZhi()); // 命宫地势
        String shenGongDiShi = shiErZhangSheng.get(dto.getDayGan() + dto.getShenGongZhi()); // 身宫地势
        // 3.5、计算空亡
        String taiYuanKongWang = kongWang.get(tyGz);  // 胎元空亡
        String taiXiKongWang = kongWang.get(txGz);    // 胎息空亡
        String mingGongKongWang = kongWang.get(mgGz); // 命宫空亡
        String shenGongKongWang = kongWang.get(sgGz); // 身宫空亡
        // 3.6、计算纳音
        String taiYuanNaYin = naYin.get(tyGz);  // 胎元纳音
        String taiXiNaYin = naYin.get(txGz);    // 胎息纳音
        String mingGongNaYin = naYin.get(mgGz); // 命宫纳音
        String shenGongNaYin = naYin.get(sgGz); // 身宫纳音
        // 3.7、计算神煞
        BaZiSetting baZiSetting = new BaZiSetting();
        BeanUtils.copyProperties(dto, baZiSetting);
        List<String> baZi = Arrays.asList(ygz, mgz, dgz, hgz);
        List<String> yunNianGanZhi = Arrays.asList(tyGz, txGz, mgGz, sgGz);
        BaZiShenShaUtil ssUtil = new BaZiShenShaUtil(baZiSetting, baZi, dto.getYearGanZhiNaYinWuXing(), dto.getSeason(), yunNianGanZhi);
        List<String> taiYuanShenSha = ssUtil.getDaYunShenSha();   // 胎元神煞
        List<String> taiXiShenSha = ssUtil.getLiuNianShenSha();   // 胎息神煞
        List<String> mingGongShenSha = ssUtil.getLiuYueShenSha(); // 命宫神煞
        List<String> shenGongShenSha = ssUtil.getLiuRiShenSha();  // 身宫神煞

        // 4、设置数据并返回
        PgBaZiTaiMingShenVo vo = new PgBaZiTaiMingShenVo();
        vo.setTianGanLiuYi(tianGanLiuYi); // 天干留意
        vo.setDiZhiLiuYi(diZhiLiuYi); // 地支留意
        vo.setTaiYuanZhuXing(taiYuanZhuXing); // 胎元主星
        vo.setTaiYuanGanZhi(tyGz); // 胎元干支
        vo.setTaiYuanCangGan(taiYuanCangGan); // 胎元藏干
        vo.setTaiYuanFuXing(taiYuanFuXing); // 胎元副星
        vo.setTaiYuanDiShi(taiYuanDiShi); // 胎元地势
        vo.setTaiYuanKongWang(taiYuanKongWang); // 胎元空亡
        vo.setTaiYuanNaYin(taiYuanNaYin); // 胎元纳音
        vo.setTaiYuanShenSha(taiYuanShenSha); // 胎元神煞
        vo.setTaiXiZhuXing(taiXiZhuXing); // 胎息主星
        vo.setTaiXiGanZhi(txGz); // 胎息干支
        vo.setTaiXiCangGan(taiXiCangGan); // 胎息藏干
        vo.setTaiXiFuXing(taiXiFuXing); // 胎息副星
        vo.setTaiXiDiShi(taiXiDiShi); // 胎息地势
        vo.setTaiXiKongWang(taiXiKongWang); // 胎息空亡
        vo.setTaiXiNaYin(taiXiNaYin); // 胎息纳音
        vo.setTaiXiShenSha(taiXiShenSha); // 胎息神煞
        vo.setMingGongZhuXing(mingGongZhuXing); // 命宫主星
        vo.setMingGongGanZhi(mgGz); // 命宫干支
        vo.setMingGongCangGan(mingGongCangGan); // 命宫藏干
        vo.setMingGongFuXing(mingGongFuXing); // 命宫副星
        vo.setMingGongDiShi(mingGongDiShi); // 命宫地势
        vo.setMingGongKongWang(mingGongKongWang); // 命宫空亡
        vo.setMingGongNaYin(mingGongNaYin); // 命宫纳音
        vo.setMingGongShenSha(mingGongShenSha); // 命宫神煞
        vo.setShenGongZhuXing(shenGongZhuXing); // 身宫主星
        vo.setShenGongGanZhi(sgGz); // 身宫干支
        vo.setShenGongCangGan(shenGongCangGan); // 身宫藏干
        vo.setShenGongFuXing(shenGongFuXing); // 身宫副星
        vo.setShenGongDiShi(shenGongDiShi); // 身宫地势
        vo.setShenGongKongWang(shenGongKongWang); // 身宫空亡
        vo.setShenGongNaYin(shenGongNaYin); // 身宫纳音
        vo.setShenGongShenSha(shenGongShenSha); // 身宫神煞
        return vo;

    }


}
